https://laihao.vaserver.com/customers
Model內容
<?php
namespace App\Models\Hairdressing;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
protected $connection = 'mysql_hairdressing';
protected $table = 'customers';
protected $primaryKey = 'id';
public $timestamps = true;
protected $fillable = [
'name',
'phone',
'email',
'gender',
'birthday',
'notes',
'allergy_notes',
'hair_notes',
'is_member',
'member_no',
];
protected $casts = [
'birthday' => 'date',
'is_member' => 'boolean',
];
public function appointments()
{
return $this->hasMany(Appointment::class, 'customer_id');
}
public function invoices()
{
return $this->hasMany(Invoice::class, 'customer_id');
}
}
這段程式碼是一個 Laravel Eloquent Model,用來對應前面 SQL 裡的 customers 資料表,並定義與 appointments、invoices 的一對多關係。下面逐行說明。 api.laravel
<?php
namespace App\Models\Hairdressing;
App\Models\Hairdressing 之下,方便在專案中以 App\Models\Hairdressing\Customer 引用。 api.laravel
use Illuminate\Database\Eloquent\Model;
Customer 會繼承它,獲得 ORM 功能(查詢、建立、更新、刪除等)。 api.laravel
class Customer extends Model
{
Customer 類別,繼承自 Model,代表這是一個 Eloquent 模型,對應資料庫中的資料表。 api.laravel
protected $connection = 'mysql_hairdressing';
mysql_hairdressing(需在 config/database.php 或 .env 中定義過)。 api.laravel
mysql 連線。 api.laravel
protected $table = 'customers';
customers。 api.laravel
customers(小寫 + 複數),這裡是明確寫出。 api.laravel
protected $primaryKey = 'id';
id。 api.laravel
public $timestamps = true;
created_at 和 updated_at 欄位,需要自動維護時間戳記。 api.laravel
created_at、updated_at 欄位。 api.laravel
protected $fillable = [
'name',
'phone',
'email',
'gender',
'birthday',
'notes',
'allergy_notes',
'hair_notes',
'is_member',
'member_no',
];
create()、fill() 等方法時,只有這裡列出的欄位可以透過陣列一次帶入,避免安全風險(例如意外更新 id 或其他敏感欄位)。 api.laravel
id、created_at、updated_at 不在這裡,因為它們由資料庫或 Eloquent 自動管理。 api.laravel
protected $casts = [
'birthday' => 'date',
'is_member' => 'boolean',
];
'birthday' => 'date':把資料庫的 date 欄位轉成 Carbon 日期物件,方便用 $customer->birthday->format('Y-m-d') 等操作。 laravel
'is_member' => 'boolean':把資料庫的 tinyint(1) 轉成 PHP 的 true/false,例如 $customer->is_member 會回傳布林值。 laravel
public function appointments()
{
return $this->hasMany(Appointment::class, 'customer_id');
}
hasMany(Appointment::class, 'customer_id') 表示:
Appointment(需在同一命名空間或加上完整 namespace)。appointments 表中的 customer_id,指向本表的 id(主鍵)。 api.laravel
$customer->appointments 取得該顧客所有預約的 Collection。 api.laravel
public function invoices()
{
return $this->hasMany(Invoice::class, 'customer_id');
}
}
hasMany(Invoice::class, 'customer_id') 表示:
Invoice。invoices 表中的 customer_id。 api.laravel
$customer->invoices 取得該顧客所有發票的 Collection。 api.laravel
<?php
namespace App\Http\Controllers;
use App\Models\Hairdressing\Customer;
use Illuminate\Http\Request;
class CustomerController extends Controller
{
public function index()
{
$customers = Customer::orderBy('created_at', 'desc')->get();
return view('hairdressing.customers.index', ['customers' => $customers]);
}
public function create()
{
return view('hairdressing.customers.create');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|max:100',
'phone' => 'required|max:20',
'email' => 'nullable|email|max:150',
'gender' => 'nullable|in:male,female,other',
'birthday' => 'nullable|date',
'notes' => 'nullable|max:255',
'allergy_notes' => 'nullable|max:255',
'hair_notes' => 'nullable|max:255',
'is_member' => 'nullable|boolean',
'member_no' => 'nullable|max:20|unique:mysql_hairdressing.customers,member_no',
]);
Customer::create([
'name' => $request->name,
'phone' => $request->phone,
'email' => $request->email,
'gender' => $request->gender,
'birthday' => $request->birthday,
'notes' => $request->notes,
'allergy_notes' => $request->allergy_notes,
'hair_notes' => $request->hair_notes,
'is_member' => $request->has('is_member'),
'member_no' => $request->member_no,
]);
return redirect()->route('customers.index')->with('success', '顧客新增成功!');
}
public function edit(Customer $customer)
{
return view('hairdressing.customers.edit', ['customer' => $customer]);
}
public function update(Request $request, Customer $customer)
{
$request->validate([
'name' => 'required|max:100',
'phone' => 'required|max:20',
'email' => 'nullable|email|max:150',
'gender' => 'nullable|in:male,female,other',
'birthday' => 'nullable|date',
'notes' => 'nullable|max:255',
'allergy_notes' => 'nullable|max:255',
'hair_notes' => 'nullable|max:255',
'is_member' => 'nullable|boolean',
'member_no' => 'nullable|max:20|unique:mysql_hairdressing.customers,member_no,' . $customer->id,
]);
$customer->update([
'name' => $request->name,
'phone' => $request->phone,
'email' => $request->email,
'gender' => $request->gender,
'birthday' => $request->birthday,
'notes' => $request->notes,
'allergy_notes' => $request->allergy_notes,
'hair_notes' => $request->hair_notes,
'is_member' => $request->has('is_member'),
'member_no' => $request->member_no,
]);
return redirect()->route('customers.index')->with('success', '顧客資料更新成功!');
}
public function destroy(Customer $customer)
{
$customer->delete();
return redirect()->route('customers.index')->with('success', '顧客已刪除!');
}
}
這是一個典型的 Laravel CRUD Controller,用來管理顧客資料(列表、新增、編輯、更新、刪除)。下面逐段、逐行說明程式碼的作用。 api.laravel
<?php
namespace App\Http\Controllers;
App\Http\Controllers 下,符合 Laravel 預設的 Controller 位置。 api.laravel
use App\Models\Hairdressing\Customer;
use Illuminate\Http\Request;
Customer 模型,之後可以用 Customer:: 呼叫 Eloquent 方法。 api.laravel
Request 類別,用來取得表單與請求的資料、進行驗證等。 api.laravel
class CustomerController extends Controller
{
CustomerController 類別,繼承自 Laravel 的基礎 Controller。 api.laravel
public function index()
{
$customers = Customer::orderBy('created_at', 'desc')->get();
return view('hairdressing.customers.index', ['customers' => $customers]);
}
index():對應顧客列表頁面的方法。 api.laravel
Customer::orderBy('created_at', 'desc')->get():
customers 資料表查詢所有資料。created_at 欄位由新到舊排序(desc)。get() 回傳一個 Eloquent Collection。 api.laravel
view('hairdressing.customers.index', ['customers' => $customers]):
resources/views/hairdressing/customers/index.blade.php 視圖。$customers 傳進視圖,在 Blade 中可以用 $customers 遍歷顯示。 api.laravel
public function create()
{
return view('hairdressing.customers.create');
}
create():回傳「新增顧客」的表單頁面。 api.laravel
resources/views/hairdressing/customers/create.blade.php。 api.laravel
public function store(Request $request)
{
store():處理新增表單提交後的邏輯,接收 Request 物件。 api.laravel
$request->validate([
'name' => 'required|max:100',
'phone' => 'required|max:20',
'email' => 'nullable|email|max:150',
'gender' => 'nullable|in:male,female,other',
'birthday' => 'nullable|date',
'notes' => 'nullable|max:255',
'allergy_notes' => 'nullable|max:255',
'hair_notes' => 'nullable|max:255',
'is_member' => 'nullable|boolean',
'member_no' => 'nullable|max:20|unique:mysql_hairdressing.customers,member_no',
]);
$request->validate([...]):對表單資料進行驗證,若失敗會自動導回並帶入錯誤訊息。 api.laravel
'name' => 'required|max:100':必填,最多 100 字,對應資料庫 varchar(100)。 api.laravel
'phone' => 'required|max:20':必填,最多 20 字,對應 varchar(20)。 api.laravel
'email' => 'nullable|email|max:150':可為空,若有值必須是合法 email,最多 150 字。 api.laravel
'gender' => 'nullable|in:male,female,other':可為空,若有值必須是 male、female 或 other,對應 enum。 api.laravel
'birthday' => 'nullable|date':可為空,若有值必須是合法日期格式。 api.laravel
'notes', 'allergy_notes', 'hair_notes':可為空,最多 255 字(你 SQL 中是 text,這裡用 255 做前端限制)。 api.laravel
'is_member' => 'nullable|boolean':可為空,必須是布林值(表單通常用 checkbox)。 api.laravel
'member_no' => 'nullable|max:20|unique:mysql_hairdressing.customers,member_no':
unique:mysql_hairdressing.customers,member_no 表示在 mysql_hairdressing 連線的 customers 表中,member_no 必須唯一。 api.laravel
Customer::create([
'name' => $request->name,
'phone' => $request->phone,
'email' => $request->email,
'gender' => $request->gender,
'birthday' => $request->birthday,
'notes' => $request->notes,
'allergy_notes' => $request->allergy_notes,
'hair_notes' => $request->hair_notes,
'is_member' => $request->has('is_member'),
'member_no' => $request->member_no,
]);
Customer::create([...]):使用大量指派(mass assignment)建立一筆新顧客資料。 api.laravel
$request 取值:
$request->name、$request->phone 等對應表單欄位名稱。 api.laravel
'is_member' => $request->has('is_member'):
is_member(例如 checkbox 被勾選),則為 true,否則 false。 api.laravel
created_at、updated_at,Eloquent 會自動填入。 api.laravel
return redirect()->route('customers.index')->with('success', '顧客新增成功!');
}
redirect()->route('customers.index'):導向名為 customers.index 的路由(通常是顧客列表頁)。 api.laravel
->with('success', '顧客新增成功!'):在 session 中暫存一則成功訊息,可在視圖中用 session('success') 顯示。 api.laravel
public function edit(Customer $customer)
{
return view('hairdressing.customers.edit', ['customer' => $customer]);
}
edit():回傳「編輯顧客」的表單頁面。 api.laravel
Customer $customer 使用路由模型綁定(Route Model Binding):
Route::get('/customers/{customer}/edit', ...),Laravel 會自動根據 {customer} 的 id 查詢對應的 Customer 模型。 api.laravel
resources/views/hairdressing/customers/edit.blade.php。 api.laravel
$customer 傳進視圖,Blade 中可用來顯示目前資料並填入表單。 api.laravel
public function update(Request $request, Customer $customer)
{
update():處理編輯表單提交後的更新邏輯。 api.laravel
Request 與要更新的 $customer 模型(同樣使用路由模型綁定)。 api.laravel
$request->validate([
'name' => 'required|max:100',
'phone' => 'required|max:20',
'email' => 'nullable|email|max:150',
'gender' => 'nullable|in:male,female,other',
'birthday' => 'nullable|date',
'notes' => 'nullable|max:255',
'allergy_notes' => 'nullable|max:255',
'hair_notes' => 'nullable|max:255',
'is_member' => 'nullable|boolean',
'member_no' => 'nullable|max:20|unique:mysql_hairdressing.customers,member_no,' . $customer->id,
]);
store() 大部分相同,差別在 member_no 的唯一性檢查。 api.laravel
'member_no' => '...unique:mysql_hairdressing.customers,member_no,' . $customer->id:
member_no 在 customers 表中是否唯一,但排除目前這筆資料($customer->id)。 api.laravel
$customer->update([
'name' => $request->name,
'phone' => $request->phone,
'email' => $request->email,
'gender' => $request->gender,
'birthday' => $request->birthday,
'notes' => $request->notes,
'allergy_notes' => $request->allergy_notes,
'hair_notes' => $request->hair_notes,
'is_member' => $request->has('is_member'),
'member_no' => $request->member_no,
]);
$customer->update([...]):對這筆顧客資料進行更新。 api.laravel
is_member 一樣用 $request->has('is_member') 判斷 checkbox 是否勾選。 api.laravel
updated_at 會由 Eloquent 自動更新為當前時間。 api.laravel
return redirect()->route('customers.index')->with('success', '顧客資料更新成功!');
}
public function destroy(Customer $customer)
{
$customer->delete();
return redirect()->route('customers.index')->with('success', '顧客已刪除!');
}
}
destroy():刪除指定的顧客資料。 api.laravel
$customer->delete():呼叫 Eloquent 的 delete() 方法,從資料庫刪除這筆資料。 api.laravel
剩下的畫面就是下次再來解說啦~